# 特殊的双下方法: 原本是开发python这个语言的程序员用的.源码中使用的.
# str : 我们不能轻易使用.慎用.
# 双下方法: 你不知道你干了什么就触发某个双下方法.

# __len__


# class B:
#
#     def __init__(self,name,age):
#         self.name = name
#         self.age =age
#
#     def __len__(self):
#         print(self.__dict__)
#
#         return len(self.__dict__)  # 2
#
# b = B('leye',28)
#
# print(len(b))

# dict
# print(len({'name': 'leye', 'age': 28}))


# class A(object):
#
#     pass
#
# obj = A()

# print(hash(obj))
# str
# print(hash('fdsaf'))


# ***

# class A:
#
#     def __init__(self,name,age):
#         self.name = name
#         self.age =age
#
#     def __str__(self):
#         print(666)
#         return f'姓名: {self.name} 年龄: {self.age}'
#
# a = A('赵海狗',35)
# b = A('李业',56)
# c = A('华丽',18)
# 打印对象触发__str__方法
# print(f'{a.name}  {a.age}')
# print(f'{b.name}  {b.age}')
# print(f'{c.name}  {c.age}')
# print(a)
# print(b)
# print(c)
# 直接str转化也可以触发.
# print(str(a))

# repr
# print('我叫%s' % ('alex'))
# print('我叫%r' % ('alex'))
# print(repr('fdsaf'))


# class A:
#
#     def __init__(self,name,age):
#         self.name = name
#         self.age =age
#
#     def __repr__(self):
#         print(666)
#         return f'姓名: {self.name} 年龄: {self.age}'
#
# a = A('赵海狗',35)
# b = A('李业',56)
# c = A('华丽',18)
# # print(a)
# print(repr(a))


# class A:
#
#     def __init__(self,name,age):
#         self.name = name
#         self.age =age
#
#     def __str__(self):
#         return '777'
#
#
#     def __repr__(self):
#         return '666'
#
# a = A('赵海狗',35)
# b = A('李业',56)
# c = A('华丽',18)
# # print(a)
# print(a)

# __call__方法  ***
# 对象() 自动触发对象从属于类(父类)的__call__方法
# class Foo:
#
#     def __init__(self):
#         pass
#
#     def __call__(self, *args, **kwargs):
#         print('__call__')
#
# obj = Foo()
# obj()


# __eq__
# class A(object):
#     def __init__(self):
#         self.a = 1
#         self.b = 2
#
#     def __eq__(self,obj):
#         # if  self.a == obj.a and self.b == obj.b:
#         #     return True
#         return True
# x = A()
# y = A()
# print(x == y)
# x = 1
# y = 2
# print(x+y)
# __del__析构方法

# class A:
#
#     def __del__(self):
#         print(666)
#
# obj = A()
# del obj

# __new__ *** new一个对象  构造方法


class A(object):

    def __init__(self):

        self.x = 1
        print('in init function')

    def __new__(cls, *args, **kwargs):
        print('in new function')
        return object.__new__(A)  # object 342534

# # 对象是object类的__new__方法 产生了一个对象.
a = A()

# 类名()
# 1. 先触发 object的__new__方法,此方法在内存中开辟一个对象空间.
# 2. 执行__init__方法,给对象封装属性.

# print(a)

# python中的设计模式: 单例模式

# 一个类只允许实例化一个对象.
# class A:
#
#     pass
# obj = A()
# print(obj)
# obj1 = A()
# print(obj1)
# obj2 = A()
# print(obj2)

# 手写单例模式
# class A:
#     __instance = None
#
#     def __init__(self,name):
#         self.name = name
#
#     def __new__(cls,*args,**kwargs):
#         if not cls.__instance:
#             cls.__instance = object.__new__(cls)
#         return cls.__instance
#
#
# obj = A('alex')
# print(obj)
# obj1 = A('李业')
# print(obj1.name)
# print(obj.name)

